#pragma once

#include "iostream"
#include "vector"
#include "algorithm"
#include "semaphore.h"
#include "pthread.h"

using namespace std;
/*HJJ QQ479287006
 *给你一个类：

public class Foo {
  public void first() { print("first"); }
  public void second() { print("second"); }
  public void third() { print("third"); }
}
三个不同的线程 A、B、C 将会共用一个 Foo 实例。

线程 A 将会调用 first() 方法
线程 B 将会调用 second() 方法
线程 C 将会调用 third() 方法
请设计修改程序，以确保 second() 方法在 first() 方法之后被执行，third() 方法在 second() 方法之后被执行。

提示：

尽管输入中的数字似乎暗示了顺序，但是我们并不保证线程在操作系统中的调度顺序。
你看到的输入格式主要是为了确保测试的全面性。

来源：力扣（LeetCode）
链接：https://leetcode.cn/problems/print-in-order
著作权归领扣网络所有。商业转载请联系官方授权，非商业转载请注明出处。
 * */

// 我擦真的得需要信号量

// java 可以用 countlanchdown
//sem_t sem12,sem23;
//void  Foo() {
//
//    sem_init(&sem12,0,0);
//    sem_init(&sem23,0,0);
//
//}
//
//void first(function<void()> printFirst) {
//
//    // printFirst() outputs "first". Do not change or remove this line.
//    printFirst();
//    sem_post(&sem12);
//
//}
//
//void second(function<void()> printSecond) {
//
//    sem_wait(&sem12);
//    // printSecond() outputs "second". Do not change or remove this line.
//    printSecond();
//
//    sem_post(&sem23);
//}
//
//void third(function<void()> printThird) {
//
//    sem_wait(&sem23);
//    // printThird() outputs "third". Do not change or remove this line.
//    printThird();
//
//
//}


pthread_mutex_t lock1 = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_t lock2 = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_t lock3 = PTHREAD_MUTEX_INITIALIZER;

//先释放12 后23
void Foo() {

    pthread_mutex_lock(&lock2);
    pthread_mutex_lock(&lock3);
}

void first(function<void()> printFirst) {

    pthread_mutex_lock(&lock1);
    printFirst();
    pthread_mutex_unlock(&lock2);

}

void second(function<void()> printSecond) {
    pthread_mutex_lock(&lock2);

    printSecond();
    pthread_mutex_unlock(&lock3);

}

void third(function<void()> printThird) {

    pthread_mutex_lock(&lock3);
    printThird();
    pthread_mutex_unlock(&lock3);

}